package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"go.uber.org/zap"
	"google.golang.org/grpc"

	"mxshop-api/goods-web/global"
	"mxshop-api/goods-web/initialize"
	"mxshop-api/goods-web/utils"
	"mxshop-api/goods-web/utils/consul"
)

func main() {
	// init logger
	initialize.InitLogger()

	// init config
	initialize.InitConfig()

	// init routers
	Router := initialize.Routers()

	// init trans
	if err := initialize.InitTrans("zh"); err != nil {
		zap.L().Fatal("init trans failed", zap.Error(err))
	}

	// init server connection
	err := initialize.InitSrvConn()
	if err != nil {
		zap.L().Fatal("init server connection failed", zap.Error(err))
	}
	defer func(Conn *grpc.ClientConn) {
		err := Conn.Close()
		if err != nil {
			zap.L().Error("cannot close grpc client connection")
		}
	}(global.Conn)

	var port = global.ServerConfig.Port
	if debug := initialize.GetEnvInfo("DEBUG"); !debug {
		port, err = utils.GetFreePort()
		if err != nil {
			zap.L().Fatal("cannot get free port", zap.Error(err))
		}
	}

	// 服务注册
	consulConf := global.ServerConfig.ConsulConfig
	c, err := consul.NewConsulRegister(fmt.Sprintf("%s:%d", consulConf.Host, consulConf.Port))
	if err != nil {
		zap.L().Fatal("cannot create consul api client", zap.Error(err))
	}

	b, err := utils.GetOutboundIP()
	if err != nil {
		zap.L().Fatal("get out bound ip failed", zap.Error(err))
	}

	ip := b.String()
	name := global.ServerConfig.Name
	tags := append(consulConf.Tags, global.ServerConfig.Name)

	err = c.RegisterService(name, ip, global.ServerConfig.Port, tags)
	if err != nil {
		zap.L().Fatal("register to consul failed", zap.Error(err))
	}

	// 启动服务
	go func() {
		zap.L().Debug("启动服务器", zap.Int("端口", port))
		if err := Router.Run(fmt.Sprintf("0.0.0.0:%d", port)); err != nil {
			zap.L().Fatal("启动失败", zap.Error(err))
		}
	}()

	// 服务注销
	quitChan := make(chan os.Signal, 1)
	signal.Notify(quitChan, syscall.SIGTERM, syscall.SIGINT)
	<-quitChan // hang住
	// 程序退出时从consul中注销服务
	serviceID := fmt.Sprintf("%s-%s-%d", name, ip, global.ServerConfig.Port)
	err = c.DeregisterService(serviceID)
	if err != nil {
		zap.L().Error("cannot deregister from consul", zap.String("service_id", serviceID), zap.Error(err))
	}
}
